<?php

/**
 * Created by 无所谓已
 * User: Administrator
 * Date: 2025-09-20
 * Time: 12:35
 */

namespace plugin\csauto\app\service;


use plugin\csauto\app\model\SiteRulesModel;
use plugin\csauto\app\model\TorrentListModel;

class SiteRulesWorkService
{
    /**
     * 来源站点判断
     */
    const RULE_TYPE_SOURCE_SITE_ID = 1;

    /**
     * 资源标签
     */
    const RULE_TYPE_SOURCE_TORRENTS_TAG = 2;

    /**
     * 资源类型
     */
    const RULE_TYPE_SOURCE_TORRENTS_TYPE = 3;

    /**
     * 资源体积(GB)
     */
    const RULE_TYPE_SOURCE_TORRENTS_SIZE = 4;

    /**
     * 资源分辨率
     */
    const RULE_TYPE_SOURCE_TORRENTS_RESOLUTION = 5;

    const RULE_FORMULA_EQUAL = 1; /* 等于 */
    const RULE_FORMULA_NOT_EQUAL = 2; /* 不等于 */
    const RULE_FORMULA_GREATER_THAN = 3; /*大于*/
    const RULE_FORMULA_LESS_THAN = 4; /*小于*/
    const RULE_FORMULA_INCLUDE = 5; /* 包含 */
    const RULE_FORMULA_NOT_INCLUDE = 6; /* 不包含 */


    /**
     * @var string[]
     */
    public static $RuleTypeENUM = array(
        SiteRulesWorkService::RULE_TYPE_SOURCE_SITE_ID => '来源站点(ID)',
        SiteRulesWorkService::RULE_TYPE_SOURCE_TORRENTS_TAG => '资源标签',
        SiteRulesWorkService::RULE_TYPE_SOURCE_TORRENTS_TYPE => '资源类型',
        SiteRulesWorkService::RULE_TYPE_SOURCE_TORRENTS_SIZE => '资源体积(GB)',
        SiteRulesWorkService::RULE_TYPE_SOURCE_TORRENTS_RESOLUTION => '资源分辨率'
    );
    /**
     * @var string[]
     */
    public static $RuleFormulaENUM = array(
        self::RULE_FORMULA_EQUAL => '等于',
        self::RULE_FORMULA_NOT_EQUAL => '不等于',
        self::RULE_FORMULA_GREATER_THAN => '大于',
        self::RULE_FORMULA_LESS_THAN => '小于',
        self::RULE_FORMULA_INCLUDE => '包含',
        self::RULE_FORMULA_NOT_INCLUDE => '不包含',
    );

    public static $RuleActionENUM = array(
        0 => '未定义',
        1 => '允许',
        2 => '拒绝',
    );


    public static function getSiteRulesList()
    {
        return SiteRulesModel::where('rule_status', 1)->orderBy('sort', 'desc')->get();
    }

    public static function checkSiteRules($siteRules, $taskData, $taskListItem, $siteId)
    {
        if (empty($taskListItem)) {
            addlog('checkSiteRules', "taskListItem 不能为空", 'error');
            addlog('checkSiteRules', $taskData);
//            return false;
            throw new \Exception('taskListItem: 获取失败');
        }
        if (empty($taskData)) {
            addlog('checkSiteRules', "taskData 不能为空", 'error');
            return false;
        }
        foreach ($siteRules as $ruleItem) {
            if (!empty($ruleItem->scope_site_id)) {
                if (count($ruleItem->scope_site_id) > 0) {
                    /*对于存在指定站点规则的内容判断一下是否在其中*/
                    if (!in_array($siteId, $ruleItem->scope_site_id)) continue;
                }
            }
            $isMatch = false;
            switch ($ruleItem->rule_type) {
                case static::RULE_TYPE_SOURCE_SITE_ID:
                    $isMatch = static::matchSiteRules($ruleItem->rule_compare, $ruleItem->rule_value, $taskData->site_id);
                    break;
                case static::RULE_TYPE_SOURCE_TORRENTS_TAG:
                    $torrentTag = json_decode($taskListItem->torrents_tag, true);
                    if (!is_array($torrentTag)) continue 2;
                    $isMatch = static::matchSiteRules($ruleItem->rule_compare, $ruleItem->rule_value, $torrentTag);
                    break;
                case static::RULE_TYPE_SOURCE_TORRENTS_TYPE:
                    $isMatch = static::matchSiteRules($ruleItem->rule_compare, $ruleItem->rule_value, $taskListItem->torrents_type);
                    break;
                case static::RULE_TYPE_SOURCE_TORRENTS_SIZE:
                    $isMatch = static::matchSiteRules($ruleItem->rule_compare, $ruleItem->rule_value, convertToGB($taskListItem->torrents_size));
                    break;
                case static::RULE_TYPE_SOURCE_TORRENTS_RESOLUTION:
                    $isMatch = static::matchSiteRules($ruleItem->rule_compare, $ruleItem->rule_value, $taskListItem->torrents_resolution);
                    break;
            }
            if ($isMatch && $ruleItem->rule_action > 0) {
                addlog("站点发布：{$siteId} , 规则匹配 结果：" . ($ruleItem->rule_action ? true : false), $ruleItem);
                return $ruleItem->rule_action == 1;
            }
        }
        /*没有拒绝规则情况下默认拒绝*/
        addlog('规则匹配', "无匹配规则 默认拒绝");
        return false;
    }

    public static function matchSiteRules($ruleCompare, $ruleValue, $taskItem)
    {
        switch ($ruleCompare) {
            case static::RULE_FORMULA_EQUAL:
            case static::RULE_FORMULA_NOT_EQUAL:
                if ($ruleValue == $taskItem) {
                    return $ruleCompare == static::RULE_FORMULA_EQUAL;
                }
                return ($ruleCompare == static::RULE_FORMULA_EQUAL) ? false : true;
                break;
            case static::RULE_FORMULA_GREATER_THAN:
                if ($ruleValue > $taskItem) {
                    return true;
                }
                break;
            case static::RULE_FORMULA_LESS_THAN:
                if ($ruleValue < $taskItem) {
                    return true;
                }
                break;
            case static::RULE_FORMULA_INCLUDE:
                if (static::optimizedMatch($taskItem, $ruleValue)) {
                    return true;
                }
                break;
            case static::RULE_FORMULA_NOT_INCLUDE:
                if (static::optimizedNotMatch($taskItem, $ruleValue)) {
                    return true;
                }
                break;
        }
        return false;
    }

    private static function optimizedMatch($target, $pattern)
    {
        // 如果 pattern 是字符串且包含逗号，则转换为数组
        if (is_string($pattern) && strpos($pattern, ',') !== false) {
            $pattern = array_map('trim', explode(',', $pattern));
        }

        // 如果 pattern 是数组，进行循环匹配
        if (is_array($pattern)) {
            foreach ($pattern as $item) {
                if (is_string($target) && strpos($target, $item) !== false) {
                    return true;
                } elseif (is_array($target) && in_array($item, $target)) {
                    return true;
                }
            }
            return false;
        } elseif (is_string($pattern)) {
            // 如果是字符串，使用字符串包含判定方式
            return strpos($target, $pattern) !== false;
        }

        // 添加对 pattern 为数组但只有一个元素的处理
        if (is_array($pattern) && count($pattern) == 1) {
            $item = reset($pattern);
            if (is_string($target) && strpos($target, $item) !== false) {
                return true;
            } elseif (is_array($target) && in_array($item, $target)) {
                return true;
            }
        }
        return false;
    }

    private static function optimizedNotMatch($target, $pattern)
    {
        // 如果 pattern 是字符串且包含逗号，则转换为数组
        if (is_string($pattern) && strpos($pattern, ',') !== false) {
            $pattern = array_map('trim', explode(',', $pattern));
        }

        // 如果 pattern 是数组，进行循环匹配（只要有一个不包含就返回true）
        if (is_array($pattern)) {
            foreach ($pattern as $item) {
                if (is_string($target) && strpos($target, $item) === false) {
                    return true; // 有一个不匹配就返回true
                } elseif (is_array($target) && !in_array($item, $target)) {
                    return true; // 有一个不匹配就返回true
                }
            }
            return false; // 全部都匹配才返回false
        } elseif (is_string($pattern)) {
            // 如果是字符串，使用字符串包含判定方式
            return strpos($target, $pattern) === false;
        }

        return false;
    }

    private static function optimizedMatchAll($target, $pattern)
    {
        // 如果 pattern 是字符串且包含逗号，则转换为数组
        if (is_string($pattern) && strpos($pattern, ',') !== false) {
            $pattern = array_map('trim', explode(',', $pattern));
        }

        // 如果 pattern 是数组，需要全部匹配
        if (is_array($pattern)) {
            foreach ($pattern as $item) {
                if (is_string($target) && strpos($target, $item) === false) {
                    return false; // 只要有一个不包含就返回false
                } elseif (is_array($target) && !in_array($item, $target)) {
                    return false; // 只要有一个不包含就返回false
                }
            }
            return true; // 全部都包含才返回true
        } elseif (is_string($pattern)) {
            // 如果是字符串，使用字符串包含判定方式
            return strpos($target, $pattern) !== false;
        }

        return false;
    }

    private static function optimizedNotMatchAny($target, $pattern)
    {
        // 如果 pattern 是字符串且包含逗号，则转换为数组
        if (is_string($pattern) && strpos($pattern, ',') !== false) {
            $pattern = array_map('trim', explode(',', $pattern));
        }

        // 如果 pattern 是数组，需要全部不匹配
        if (is_array($pattern)) {
            foreach ($pattern as $item) {
                if (is_string($target) && strpos($target, $item) !== false) {
                    return false; // 只要有一个包含就返回false
                } elseif (is_array($target) && in_array($item, $target)) {
                    return false; // 只要有一个包含就返回false
                }
            }
            return true; // 全部都不包含才返回true
        } elseif (is_string($pattern)) {
            // 如果是字符串，使用字符串包含判定方式
            return strpos($target, $pattern) === false;
        }

        return true;
    }
}
